<template>
  <div class="monaco" id="monaco" ref="monacoRef"></div>
</template>

<script setup>
import * as monaco from "monaco-editor";
import { onMounted, ref, onBeforeUnmount, watch } from "vue";

const props = defineProps({
  code: {
    type: String,
    required: true,
  },
  theme: {
    type: String,
    required: true,
    default: "vs",
  },
  getEditor: {
    type: Function,
    default: (editor) => {},
  },
});

const monacoRef = ref(null);
let editor = null;
let decorations = []; // 存储装饰的ID

const highlightLine = () => {
  const lineNumber = Number(0);
  if (lineNumber === 0) {
    decorations = editor.deltaDecorations(decorations, []);
    return;
  }
  decorations = editor.deltaDecorations(decorations, [
    {
      range: new monaco.Range(lineNumber, 1, lineNumber, 1),
      options: {
        isWholeLine: true,
        className: "highlight-line",
      },
    },
  ]);
};

const setLanguage = () => {
  if (!editor) {
    return;
  }
  const model = editor.getModel();
  if (!model) {
    return;
  }
  monaco.editor.setModelLanguage(model, props.language);
};

const setPosition = () => {
  if (!editor) {
    return;
  }
  editor.revealLineInCenter(Number(0));
};
const init = () => {
  editor = monaco.editor.create(monacoRef.value, {
    value: props.code,
    language: "javascript",
    theme: props.theme,
    automaticLayout: true, // 自动调整大小
    lineHeight: 24,
    tabSize: 2,
    fontSize: 16,
    domReadOnly: true,
  });
};

const assignmentCode = () => {
  if (!editor) {
    return;
  }
  editor.setValue(props.code);
  if (props.code) {
    setLanguage();
    setPosition();
    highlightLine();
  }
};

const setTheme = () => {
  if (!editor) {
    return;
  }
  monaco.editor.setTheme(props.theme);
};
watch(() => props.code, assignmentCode, { immediate: true, deep: true });
watch(() => props.theme, setTheme, { immediate: true, deep: true });

onMounted(() => {
  init();
  props.getEditor(editor);
});

onBeforeUnmount(() => {
  if (editor) {
    editor.dispose();
    editor = null;
  }
});
</script>

<style scoped lang="scss">
.monaco {
  width: 100%;
  height: 100%;
}
</style>

<style>
#monaco .highlight-line {
  background-color: rgba(140, 143, 255, 0.7) !important; /* 设置高亮背景颜色 */
}
</style>
